#include <iostream>
#include <fstream>

#include <stdlib.h>
#include <stdio.h>

#include <iostream>
#include <cstdlib>
//#include <new>
using namespace std;


#ifndef MATRX_H
#define MATRX_H
#include "vectr.h"




template <class M> class matrx
{
     private:
        int row,column;
        M *m;		//M **m;// modifica del codice mazzarella
     public:
		matrx(){row=0;column=0;m=NULL; }//si usa in concomitanza con la fz initialize quando,all'inizio non conosci il num di righe e colonne
        matrx(int a,int b);//alloca memoria alla matrice e la inizializza con tutti zeri


		matrx (const matrx& a);
		const matrx& operator=(const matrx &a);

		void AppendAhead( const vectr<M> a);//appende in testa un vettore riga
		void Append( const vectr<M> a);//appende in testa un vettore riga
		void SwapRow(int i,int j);
																			//	void AppendAhead( const matrx & a);//appende in testa una matrice non mi serve quindi non l'ho implementato!!!!!!
        void AppendCol( const vectr<M> a);		//AGGIUNTO DA ME MEDESIMO
		vectr<M>	get_IthRow(int i)	const ;
		vectr<M>	get_IthCol(int i)	const ;
		matrx<M>	get_minore(int X0,int Y0,int X1,int Y1)	const;
		void set_IthRow(int i, vectr<M> v);		//AGGIUNTO DA ME MEDESIMO


		void put(int k,int l,M data){if(k<row && l<column) m[l+k*column]=data;/*m[k][l]=data; */else cout<<"index out range of the matrix!!!\n"; 
                   }//inserimento elemento (i,j)
		M get (int i,int j) const{return m[j+column*i];}/*if(i<row && j<column)*/ //return m[i][j];/*else {cout<<"index cazzoout range of the matrix\n";system("PAUSE");exit(1);}*/}
        int get_row()const{return row;}
        int get_column()const{return column;}
        int get_row_T()const{return column;}
        int get_column_T()const{return row;}
        matrx productmatrix(matrx mat1,matrx mat2);//prodotto tra 2 matrici
	    void printmatrix();//stampa la matrice per intero
	    
		
		void initialize(int r,int c); //alloca memoria alla matrice e la inizializza con tutti zeri
        M matrixT(int i,int j);//restituisce l'elemento (i,j) della matrice trasposta
		~matrx(){/*int i;for(i=0;i<row;i++)delete [] m[i];*/delete [] m;}//cout<<"object deallocate\n";}

		// Francesco (21/01/09): nuova versione per stampaer la matrice su grafo 
		void printmatrix(ostream &out_stream);//stampa la matrice per intero


		void PrintGraph(const char *FileName);
		bool IsEqual2AdjMtx( const matrx<M> & m, int & DiffNum, bool printOut= false);
		bool IsEqual2AdjMtx( const matrx<M> & m, int & DiffNum, int &  missing,int & extra,int & reversed,bool printOut= false);

		void  LoadMtrx(const char * FileName);
		void  LoadMtrxAdj(const char * fileGraph,float & Bdeu,float & MDL, float & MDL2);
};

#endif





